﻿using Microsoft.AspNetCore.Http;
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using TomNet.Attributes;
using TomNet.Core.Options;
using TomNet.Data;
using TomNet.Entity;
using TomNet.Extensions;
using FileInfo = TomNet.Data.FileInfo;


namespace Iot.AspNetCore
{
    [SingleInstance]
    public class UploadHelper
    {
        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="file">文件域</param>
        /// <param name="options">策略</param>
        /// <param name="flag">自定义标识</param>
        /// <param name="cancellationToken">异步操作标识</param>
        /// <returns>操作结果</returns>
        public async Task<OpResult<FileInfo>> UploadAsync(
            IFormFile file,
            UploadOptions options,
            string flag = "",
            CancellationToken cancellationToken = default)
        {
            var res = new OpResult<FileInfo>();

            if (file == null || file.Length < 1)
            {
                return res.NotOK(status: ApiResultCode.MissingParameter, msg: "请上传文件！");
            }

            //格式限制
            if (!options.ContentType.Contains(file.ContentType))
            {
                return res.NotOK(status: ApiResultCode.InvalidParamater, msg: "文件格式错误");
            }

            //大小限制
            if (!(file.Length <= options.MaxSize))
            {
                return res.NotOK(status: ApiResultCode.InvalidParamater, msg: "文件过大");
            }

            var fileInfo = new FileInfo(file.FileName, file.Length)
            {
                UploadPath = options.UploadPath,
                RequestPath = options.RequestPath
            };

            var dateTimeFormat = options.DateTimeFormat.IsNullOrEmpty() ? "" : DateTime.Now.ToString(options.DateTimeFormat);
            var format = options.Flag.IsNullOrEmpty() ? "" : string.Format(options.Flag, flag);
            fileInfo.RelativePath = Path.Combine(dateTimeFormat, format).ToPath();

            if (!Directory.Exists(fileInfo.FileDirectory))
            {
                Directory.CreateDirectory(fileInfo.FileDirectory);
            }

            fileInfo.SaveName = $"{IdWorkerHelper.GenId64()}.{fileInfo.Extension}";

            await SaveAsync(file, fileInfo.FilePath, cancellationToken);

            return res.OK(data: fileInfo);
        }

        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="file">文件域</param>
        /// <param name="filePath">路径</param>
        /// <param name="cancellationToken">异步操作标识</param>
        /// <returns>异步任务</returns>
        public async Task SaveAsync(IFormFile file, string filePath, CancellationToken cancellationToken = default)
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream, cancellationToken);
            }
        }
    }
}
